﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Db4objects.Db4o;

namespace ADB_QuanLyThuVien
{
    public class DAO_PhieuMuon
    {

        internal static string AddPhieuMuon(PhieuMuon pm, List<Book> lBook, Account acc, string emailReader)
        {
            string tmp = "";
            //if (isStillBorrow(pm.Reader) == true)
            //    tmp = "Số sách chưa trả đã đủ số lượng mượn của 1 độc giả...Hãy trả sách để được mượn thêm";
            //else
            //{
                tmp = "Sách mượn thành công:\n";
                Member employee = DAO_Member.SelectMember(acc);    
                List<Book> lBookRequest = new List<Book>();
                var config = Db4oEmbedded.NewConfiguration();
                config.Common.ObjectClass(typeof(PhieuMuon)).CascadeOnUpdate(true);
                IObjectContainer db = Db4oEmbedded.OpenFile(config, QLTV_System.ConnectString);
                //Lấy mã cho phiếu mượn
                pm.IdForm = GetNextId();
                
                //Trỏ đến đối tượng độc giả
                Member reader = new Member();
                reader.Email = emailReader;
                IObjectSet rReader = db.QueryByExample(reader);
                pm.Reader = (Member)rReader.Next();

                //Trỏ đến đối tượng nhân viên
                
                IObjectSet rEmployee = db.QueryByExample(employee);
                pm.Employee = (Member)rEmployee.Next();
                
                //Trỏ đến đối tượng sách
                for (int i = 0; i < lBook.Count; ++i)
                {
                    IList<Book> result = db.Query(delegate(Book book)
                    {
                        if (lBook[i].MaSach == book.MaSach && book.Soluong >= 1)
                            return true;
                        return false;
                    }
                    );
                    if (result.Count > 0)
                    {
                        Book sach = (Book)result[0];
                        sach.Soluong -= 1;
                        sach.LuotMuon += 1;
                        pm.LBook.Add(sach);
                        tmp += lBook[i].TenSach + " \n";
                    }
                    else
                        lBookRequest.Add(lBook[i]);
                }
                db.Store(pm);
                db.Close();
                if (lBookRequest.Count > 0)
                {
                    DAO_RequestForm.AddBookRequest(emailReader, lBookRequest);
                    tmp += "\nĐã chuyển vào danh sách chờ các sách:\n";
                    for (int i = 0; i < lBookRequest.Count; ++i)
                        tmp += lBookRequest[i].TenSach + "\n";
                }
            //}
            return tmp;
        }
        private static string GetNextId()
        {
            string id = "PM";
            DateTime now = DateTime.Now;
            id += now.Year.ToString("0000") + now.Month.ToString("00") + now.Day.ToString("00") + now.Hour.ToString("00") + now.Minute.ToString("00") + now.Second.ToString("00");
            return id;
        }

        //private static int BorrowAvailable(Member member)
        //{
        //    var config = Db4oEmbedded.NewConfiguration();
        //    config.Common.ObjectClass(typeof(PhieuMuon)).CascadeOnUpdate(true);
        //    IObjectContainer db = Db4oEmbedded.OpenFile(config, QLTV_System.ConnectString);

        //    db.Close();

        //}

        internal static string AddBFFRF(PhieuMuon pm, List<Book> lBook, Account acc, string emailReader)
        {
            string kq = "";
            kq = "Sách mượn thành công:\n";
            Member employee = DAO_Member.SelectMember(acc);
            List<Book> lBookRequest = new List<Book>();
            var config = Db4oEmbedded.NewConfiguration();
            config.Common.ObjectClass(typeof(PhieuMuon)).CascadeOnUpdate(true);
            IObjectContainer db = Db4oEmbedded.OpenFile(config, QLTV_System.ConnectString);
            //Lấy mã cho phiếu mượn
            pm.IdForm = GetNextId();

            //Trỏ đến đối tượng độc giả
            Member reader = new Member();
            reader.Email = emailReader;
            IObjectSet rReader = db.QueryByExample(reader);
            pm.Reader = (Member)rReader.Next();

            //Trỏ đến đối tượng nhân viên
            IObjectSet rEmployee = db.QueryByExample(employee);
            pm.Employee = (Member)rEmployee.Next();

            //Trỏ đến đối tượng Phiếu đặt sách
            RequestForm rqfff = new RequestForm();
            rqfff.Reader.Email = emailReader;
            IObjectSet rPDK = db.QueryByExample(rqfff);
            RequestForm rqff = (RequestForm)rPDK.Next();
            pm.rqf = rqff;

            //Trỏ đến đối tượng sách
            for (int i = 0; i < lBook.Count; ++i)
            {
                IList<Book> result = db.Query(delegate(Book book)
                {
                    if (lBook[i].MaSach == book.MaSach && book.Soluong >= 1)
                        return true;
                    return false;
                }
                );
                if (result.Count > 0)
                {
                    Book sach = (Book)result[0];
                    sach.Soluong -= 1;
                    sach.LuotMuon += 1;
                    pm.LBook.Add(sach);
                    kq += lBook[i].TenSach + " \n";
                    for (int j = 0; j < rqff.lBookRequest.Count; ++j)
                    {
                        if (rqff.lBookRequest[j].bookRequest.MaSach == sach.MaSach)
                            rqff.lBookRequest[j].IsBorrow = true;
                        break;
                    }
                }
                else
                    lBookRequest.Add(lBook[i]);
            }
            db.Store(rqff);
            db.Store(pm);
            db.Close();
            if (lBookRequest.Count > 0)
            {
                DAO_RequestForm.AddBookRequest(emailReader, lBookRequest);
                kq += "\nĐã chuyển vào danh sách chờ các sách:\n";
                for (int i = 0; i < lBookRequest.Count; ++i)
                    kq += lBookRequest[i].TenSach + "\n";
            }
            //}
            return kq;
        }

        internal static List<PhieuMuon> SelectPhieuMuon(string email)
        {
            List<PhieuMuon> list = new List<PhieuMuon>();
            IObjectContainer db = Db4oEmbedded.OpenFile(QLTV_System.ConnectString);
            PhieuMuon pm = new PhieuMuon();
            //pm.Reader.Email = email;
            IObjectSet result = db.QueryByExample(pm);
            for (int i = 0; i < result.Count; ++i)
            {
                PhieuMuon pm1 = (PhieuMuon)result[i];
                if (pm1.Reader.Email == email)
                    list.Add(pm1);
            }
            db.Close();
            return list;
        }

        internal static List<Member> SelectMember()
        {
            List<Member> mem = new List<Member>();
            IObjectContainer db = Db4oEmbedded.OpenFile(QLTV_System.ConnectString);
            IList<PhieuMuon> result = db.Query(delegate(PhieuMuon pm)
            {
                return true;
            }
            );
            for (int i = 0; i < result.Count; ++i)
                mem.Add(result[i].Reader);
            db.Close();
            return mem;
        }

        internal static List<Book> SelectBorrowBook(string idForm)
        {
            List<Book> list = new List<Book>();
            IObjectContainer db = Db4oEmbedded.OpenFile(QLTV_System.ConnectString);
            PhieuMuon pm = new PhieuMuon();
            pm.IdForm = idForm;
            IObjectSet result = db.QueryByExample(pm);
            PhieuMuon pm1 = (PhieuMuon)result.Next();
            IList<PhieuTra> resultTra = db.Query(delegate(PhieuTra rq) // câu truy vấn theo nagative query
            {
                if (rq.pm.IdForm == idForm)
                    return true;
                return false;
            }
            );
            List<Book> lTra = new List<Book>();
            for (int i = 0; i < resultTra.Count; ++i)
            {
                PhieuTra pt = (PhieuTra)resultTra[i];
                for (int j = 0; j < pt.LBook.Count; ++j)
                {
                    lTra.Add(pt.LBook[j]);
                }
            }
            
            for (int i = 0; i < pm1.LBook.Count; ++i)
            {
                int j;
                for (j = 0; j < lTra.Count; ++j)
                    if (lTra[j] == pm1.LBook[i])
                        break;
                if (j == lTra.Count)
                    list.Add(pm1.LBook[i]);
            }
            db.Close();
            return list;
        }

        internal static Book SelectBorrowBookByName(string bookname, string maphieu)
        {
            Book sach = new Book();
            IObjectContainer db = Db4oEmbedded.OpenFile(QLTV_System.ConnectString);
            PhieuMuon pm = new PhieuMuon();
            IObjectSet result = db.QueryByExample(pm);
            PhieuMuon pm1 = new PhieuMuon();
            for (int i = 0; i < result.Count; ++i)
            {
                pm1 = (PhieuMuon)result[i];
                if (pm1.IdForm == maphieu)
                    break;
            }
            for (int j = 0; j < pm1.LBook.Count; ++j)
                if (pm1.LBook[j].TenSach == bookname)
                {
                    sach = pm1.LBook[j];
                    break;
                }
            db.Close();
            return sach;
        }

        internal static PhieuMuon SelectPhieuMuonById(string idPhieuMuon)
        {
            PhieuMuon pm1 = new PhieuMuon();
            IObjectContainer db = Db4oEmbedded.OpenFile(QLTV_System.ConnectString);
            PhieuMuon pm = new PhieuMuon();
            IObjectSet result = db.QueryByExample(pm);
            for (int i = 0; i < result.Count; ++i)
            {
                pm1 = (PhieuMuon)result[i];
                if (pm1.IdForm == idPhieuMuon)
                    break;
            }
            db.Close();
            return pm1;
        }

        internal static List<Member> SelectMemberNotRB()
        {
            List<Member> mem = new List<Member>();
            IObjectContainer db = Db4oEmbedded.OpenFile(QLTV_System.ConnectString);
            IList<PhieuMuon> result = db.Query(delegate(PhieuMuon pm)
            {
                return true;
            }
            );
            List<PhieuMuon> lPhieuMuon = new List<PhieuMuon>();
            for (int i = 0; i < result.Count; ++i)
            {
                lPhieuMuon.Add( (PhieuMuon)result[i]);
            }
            db.Close();
            for (int i = 0; i < lPhieuMuon.Count; ++i)
            {
                if (isNotRF(lPhieuMuon[i])== true)
                    mem.Add(lPhieuMuon[i].Reader);
            }
            return mem;
        }

        private static bool isNotRF(PhieuMuon pm1)
        {
            List<Book> list = new List<Book>();
            IObjectContainer db = Db4oEmbedded.OpenFile(QLTV_System.ConnectString);
            IList<PhieuTra> resultTra = db.Query(delegate(PhieuTra rq) // câu truy vấn theo nagative query
            {
                if (rq.pm.IdForm == pm1.IdForm)
                    return true;
                return false;
            }
            );
            List<Book> lTra = new List<Book>();
            for (int i = 0; i < resultTra.Count; ++i)
            {
                PhieuTra pt = (PhieuTra)resultTra[i];
                for (int j = 0; j < pt.LBook.Count; ++j)
                {
                    lTra.Add(pt.LBook[j]);
                }
            }

            for (int i = 0; i < pm1.LBook.Count; ++i)
            {
                int j;
                for (j = 0; j < lTra.Count; ++j)
                    if (lTra[j] == pm1.LBook[i])
                        break;
                if (j == lTra.Count)
                    list.Add(pm1.LBook[i]);
            }
            db.Close();
            if (list.Count == 0)
                return false;
            return true;
        }



        internal static List<PhieuMuon> SelectAll()
        {
            List<PhieuMuon> list = new List<PhieuMuon>();
            IObjectContainer db = Db4oEmbedded.OpenFile(QLTV_System.ConnectString);
            IList<PhieuMuon> result = db.Query(delegate(PhieuMuon pm)
            {
                return true;
            }
            );
            for (int i = 0; i < result.Count; ++i)
                list.Add((PhieuMuon)result[i]);
            db.Close();
            return list;
        }
    }
}
